package com.vsc.print_service.util;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import javax.print.*;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Sides;
import java.awt.print.*;
import java.io.*;
import java.net.URL;
import java.util.Properties;
import java.util.UUID;

public class PrintUtil {

    static Properties properties = null;
    static Logger logger = LoggerFactory.getLogger(MessageUtils.class);

    public static void loadMessage() throws UnsupportedEncodingException, IOException {
        properties = new Properties();
        properties.load(new InputStreamReader(MessageUtils.class.getResourceAsStream("/application.properties"), "UTF-8"));
    }

    static {
        try {
            loadMessage();
        } catch (IOException e) {
            logger.error(e.getMessage());
        }
    }

    // 传入文件和打印机名称
    // 打印image
    public static boolean imagePrint(File file, String printerName) throws PrintException {
        if (file == null) {
            System.err.println("缺少打印文件");
        }
        InputStream fis = null;

        try {
            fis = new FileInputStream(file); // 构造待打印的文件流
            return imagePrint(fis, printerName);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
            return false;
        } finally {
            // 关闭打印的文件流
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static boolean imagePrint(InputStream fis, String printerName) throws PrintException {
        if (fis == null) {
            System.err.println("缺少打印文件");
            throw new ApiException(MessageCode.CODE_PARAMETER_ERROR);
        }
        try {
            // 设置打印格式，如果未确定类型，可选择autosense
            DocFlavor flavor = DocFlavor.INPUT_STREAM.JPEG;
            // 设置打印参数
            PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
            aset.add(new Copies(1)); //份数
            //aset.add(MediaSize.ISO.A4); //纸张
            // aset.add(Finishings.STAPLE);//装订
            aset.add(Sides.DUPLEX);//单双面
            // 定位打印服务
            PrintService printService = null;
            if (printerName != null) {
                //获得本台电脑连接的所有打印机
                PrintService[] printServices = PrinterJob.lookupPrintServices();
                if (printServices == null || printServices.length == 0) {
                    System.out.print("打印失败，未找到可用打印机，请检查。");
                    return false;
                }
                //匹配指定打印机
                for (int i = 0; i < printServices.length; i++) {
                    System.out.println(printServices[i].getName());
                    if (printServices[i].getName().contains(printerName)) {
                        printService = printServices[i];
                        break;
                    }
                }
                if (printService == null) {
                    System.out.print("打印失败，未找到名称为" + printerName + "的打印机，请检查。");
                    return false;
                }
            }
            Doc doc = new SimpleDoc(fis, flavor, null);
            DocPrintJob job = printService.createPrintJob(); // 创建打印作业
            job.print(doc, aset);
            return true;
        } finally {
            // 关闭打印的文件流
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    // 打印pdf
    public static boolean PDFPrint(File file ,String printerName) throws Exception {
        PDDocument document = null;
        try {
            document = PDDocument.load(file);
            PrinterJob printJob = PrinterJob.getPrinterJob();
            printJob.setJobName(file.getName());
            return printPdf(printerName, document, printJob);
        }finally {
            if (document != null) {
                try {
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    // 打印pdf
    public static boolean PDFPrint(InputStream fis ,String printerName) throws Exception {
        PDDocument document = null;
        try {
            document = PDDocument.load(fis);
            PrinterJob printJob = PrinterJob.getPrinterJob();
            printJob.setJobName(UUID.randomUUID().toString());
            return printPdf(printerName, document, printJob);
        }finally {
            if (document != null) {
                try {
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static boolean printPdf(String printerName, PDDocument document, PrinterJob printJob) throws PrinterException {
        if (printerName != null) {
            // 查找并设置打印机
            //获得本台电脑连接的所有打印机
            PrintService[] printServices = PrinterJob.lookupPrintServices();
            if (printServices == null || printServices.length == 0) {
                System.out.print("打印失败，未找到可用打印机，请检查。");
                return false;
            }
            PrintService printService = null;
            //匹配指定打印机
            for (int i = 0; i < printServices.length; i++) {
                System.out.println(printServices[i].getName());
                if (printServices[i].getName().contains(printerName)) {
                    printService = printServices[i];
                    break;
                }
            }
            if (printService != null) {
                printJob.setPrintService(printService);
            } else {
                System.out.print("打印失败，未找到名称为" + printerName + "的打印机，请检查。");
                return false;
            }
        }
        //设置纸张及缩放
        PDFPrintable pdfPrintable = new PDFPrintable(document, Scaling.ACTUAL_SIZE);
        //设置多页打印
        Book book = new Book();
        PageFormat pageFormat = new PageFormat();
        //设置打印方向
        pageFormat.setOrientation(PageFormat.PORTRAIT);//纵向
        pageFormat.setPaper(getPaper());//设置纸张
        book.append(pdfPrintable, pageFormat, document.getNumberOfPages());
        printJob.setPageable(book);
        printJob.setCopies(1);//设置打印份数
        //添加打印属性
        HashPrintRequestAttributeSet pars = new HashPrintRequestAttributeSet();
        pars.add(Sides.DUPLEX); //设置单双页
        printJob.print(pars);
        return true;
    }

    public static File getNetUrlHttp(String path){
        String fileRootPath = properties.getProperty("file.root.path");

        //对本地文件命名，path是http的完整路径，主要得到资源的名字
        String newUrl = path;
        newUrl = newUrl.split("[?]")[0];
        String[] bb = newUrl.split("/");
        //得到最后一个分隔符后的名字
        String fileName = bb[bb.length - 1];

        //保存到本地的路径
        String filePath= fileRootPath + fileName;

        File file = null;

        URL urlfile;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try{
            //判断文件的父级目录是否存在，不存在则创建
            file = new File(filePath);
            if(!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
            }
            try{
                //创建文件
                file.createNewFile();
            }catch (Exception e){
                e.printStackTrace();
            }
            //下载
            urlfile = new URL(newUrl);
            inputStream = urlfile.openStream();
            outputStream = new FileOutputStream(file);

            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead=inputStream.read(buffer,0,8192))!=-1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (null != outputStream) {
                    outputStream.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    public static Paper getPaper() {
        Paper paper = new Paper();
        // 默认为A4纸张，对应像素宽和高分别为 595, 842
        int width = 595;
        int height = 842;
        // 设置边距，单位是像素，10mm边距，对应 28px
        int marginLeft = 10;
        int marginRight = 0;
        int marginTop = 10;
        int marginBottom = 0;
        paper.setSize(width, height);
        // 下面一行代码，解决了打印内容为空的问题
        paper.setImageableArea(marginLeft, marginRight, width - (marginLeft + marginRight), height - (marginTop + marginBottom));
        return paper;
    }

    public static void main(String[] args) throws PrintException {
        imagePrint(getNetUrlHttp("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201807%2F05%2F20180705145959_mloje.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1619078647&t=99c3591f253c09eb01ea7fa295c55650"), "OKI-B410-FB9031");
    }
}
